package com.hwtx.form.util;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;


public class DateUtil {

    public static final String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss.SSS";


    private static final Map<String, ThreadLocal<Calendar>> calendars = new HashMap<>();

    /**
     * 格式化日期
     *
     * @param locale 地区/语言, 格式化月份, 星期几时根据地区语言,
     *               如MMMMM(zh:一月, en:January)MMMM(zh:一月, en:Jan) EEE(zh:星期五, en:Fri) EEEE(en:Friday)
     * @param date   日期
     * @param format 格式
     * @return String
     */
    public static String format(Locale locale, ZoneId zone, Date date, String format) {
        if (null == date || null == format)
            return null;
        LocalDateTime datetime = localDateTime(date, zone);
        return datetime.format(DateTimeFormatter.ofPattern(format, locale));
    }

    public static String format(Locale locale, ZoneId zone, Date date) {
        return format(locale, zone, date, FORMAT_FULL);
    }

    public static String format(Date date, String format) {
        return format(Locale.getDefault(), ZoneId.systemDefault(), date, format);
    }

    public static String format(Date date) {
        return format(Locale.getDefault(), ZoneId.systemDefault(), date);
    }


    public static Date parse(Long value) {
        return new Date(value);
    }

    public static Date parse(java.sql.Date value) {
        return new Date(value.getTime());
    }

    public static Date parse(java.sql.Time value) {
        return new Date(value.getTime());
    }

    public static Date parse(LocalDate value) {
        return Date.from(value.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    public static Date parse(LocalDateTime value) {
        return Date.from(value.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date parse(LocalTime value) {
        return Date.from(value.atDate(LocalDate.now()).atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date parse(Timestamp value) {
        return new Date(value.getTime());
    }

    public static Date parse(Object value) throws RuntimeException {
        Date date = null;
        if (null != value) {
            if (value.getClass() == Date.class) {
                date = (Date) value;
            } else if (value instanceof Timestamp) {
                date = parse((Timestamp) value);
            } else if (value instanceof java.sql.Date) {
                date = parse((java.sql.Date) value);
            } else if (value instanceof java.sql.Time) {
                date = parse((java.sql.Time) value);
            } else if (value instanceof Long) {
                date = parse((Long) value);
            } else if (value instanceof LocalDate) {
                date = parse((LocalDate) value);
            } else if (value instanceof LocalTime) {
                date = parse((LocalTime) value);
            } else if (value instanceof LocalDateTime) {
                date = parse((LocalDateTime) value);
            } else if (value instanceof String) {
                if (BasicUtil.isNumber(value)) {
                    Long timestamp = BasicUtil.parseLong(value, 0L);
                    date = parse(timestamp);
                } else {
                    throw new UnsupportedOperationException("不支持转化为Date类型，input = " + value);
                }
            }
        }
        return date;
    }


    public static LocalDateTime localDateTime(Date date, ZoneId zone) {
        if (null == date) {
            return null;
        }
        return date.toInstant().atZone(zone).toLocalDateTime();
    }


}
